<h1>极速、零配置的 web 应用打包工具, 同时支持 react 和 vue 的单页面应用,提供开箱即用支持 ,基于 webpack</h1>
<h1>webpack-react-vue-spa-awesome-config</h1>
<p><a href="https://github.com/masx200/webpack-react-vue-spa-awesome-config">https://github.com/masx200/webpack-react-vue-spa-awesome-config</a></p>
<h2>webpack-react-vue-spa-awesome-config 是一个命令行工具，也可以下载本软件包，自定义 webpack 配置，启动示例</h2>
<h3>极速、零配置的 web 应用打包工具, 同时支持 react 和 vue 的单页面应用,提供开箱即用支持</h3>
<h3>Fast, zero-configuration web application packaging tool that supports both single-page applications for react and vue, out-of-the-box support</h3>
<h1>基于 webpack, 同时支持 react 和 vue 的单页面应用 通用的 webpack 配置文件,提供开箱即用支持</h1>
<h2>无需配置：您无需配置任何内容。为您处理开发和生产构建的相当好的配置，以便您可以专注于编写代码。</h2>
<h1>少学习 您无需学习和配置许多构建工具。即时重新加载可帮助您专注于开发。在部署时，您的捆绑包会自动优化。</h1>
<p>愿世上再无 webpack 配置师</p>
<p><a href="https://github.com/masx200/webpack-react-vue-spa-awesome-config/blob/master/bin/index.js">查看源代码 ./bin/index.js</a></p>
<p><a href="https://github.com/masx200/webpack-react-vue-spa-awesome-config/blob/master/release/config/webpack.config.js">查看源代码 ./release/config/webpack.config.js</a></p>
<p><img loading='lazy' src="https://masx200.github.io/masx200-github-io/image/react.JPG" alt="react"></p>
<p><img loading='lazy' src="https://masx200.github.io/masx200-github-io/image/vue.JPG" alt="vue"></p>
<p><img loading='lazy' src="https://masx200.github.io/masx200-github-io/image/webpack.JPG" alt="webpack"></p>
<h1>配置一些其他的加载器的选项的文件</h1>
<p>&quot;babel.config.js&quot;</p>
<p>&quot;tsconfig.json&quot;</p>
<p>&quot;postcss.config.js&quot;</p>
<p>&quot;terser.config.js&quot;</p>
<h1>更新：添加了 <code>fork-ts-checker-webpack-plugin</code></h1>
<h1>更新：添加了 <code>ts-loader</code></h1>
<h1>更新 ：支持 <code>vue3</code> 和 <code>vue-loader16</code> 了</h1>
<h1>更新 ：使用<code>@next/react-refresh-utils</code>支持 React 热更新了</h1>
<h1>更新 : 命令行程序支持的参数</h1>
<h2>开发模式</h2>
<p><code>start</code></p>
<h2>生产模式</h2>
<p><code>build</code></p>
<h2>开发模式</h2>
<p><code>--mode=development</code></p>
<h2>生产模式</h2>
<p><code>--mode=production</code></p>
<h2>使用的自定义配置文件</h2>
<p><code>--config=webpack.config.js</code></p>
<h2>输出文件公共的网址</h2>
<p><code>--output-public-path=https://masx200.github.io/</code></p>
<h1>更新 :新增 <code>babel-plugin-htm</code> ,支持<code>HTM (Hyperscript Tagged Markup)</code></h1>
<p><a href="https://github.com/developit/htm">https://github.com/developit/htm</a></p>
<h1>更新!可以通过命令行传入 --output-public-path= 参数</h1>
<p><code>publicPath</code>指定在浏览器中引用时输出文件的公共 URL 地址。</p>
<p>The <code>publicPath</code> specifies the public URL address of the output files when referenced in a browser.</p>
<h1>新版本! 可以通过 npm 或者 yarn 安装 github 仓库的模块了!</h1>
<h1>使用方法</h1>
<h3>初始化 package.json</h3>
<p>如果没有初始化 package.json，请先初始化</p>
<p>运行</p>
<pre><code>yarn <span class="hljs-keyword">init</span>
</code></pre>
<h2>局部安装</h2>
<pre><code class="hljs language-shell">yarn add @masx200/webpack-react-vue-spa-awesome-config
</code></pre>
<p>设置<code>package.json</code></p>
<pre><code class="hljs language-json"><span class="hljs-punctuation">{</span>
    <span class="hljs-attr">&quot;scripts&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
        <span class="hljs-attr">&quot;start&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;webpack-react-vue-spa-awesome-config start&quot;</span><span class="hljs-punctuation">,</span>
        <span class="hljs-attr">&quot;build&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;webpack-react-vue-spa-awesome-config build&quot;</span>
    <span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span>
</code></pre>
<h2>安装依赖</h2>
<pre><code>yarn install
</code></pre>
<h2>开发模式</h2>
<p>启动 webpack-dev-server</p>
<pre><code>yarn <span class="hljs-keyword">start</span>
</code></pre>
<p>或者</p>
<pre><code>npm <span class="hljs-keyword">start</span>
</code></pre>
<h2>生产模式</h2>
<p>启动 webpack</p>
<pre><code>yarn build
</code></pre>
<p>或者</p>
<pre><code>npm run build
</code></pre>
<h2>全局安装</h2>
<pre><code class="hljs language-shell">yarn global add @masx200/webpack-react-vue-spa-awesome-config
</code></pre>
<h2>开发模式</h2>
<p>启动 webpack-dev-server</p>
<pre><code>webpack-react-vue-spa-awesome-<span class="hljs-built_in">config</span> start
</code></pre>
<h2>生产模式</h2>
<p>启动 webpack</p>
<pre><code>webpack-react-vue-spa-awesome-<span class="hljs-built_in">config</span> build
</code></pre>
<h1>入口文件</h1>
<p>是&quot;public/index.html&quot;和&quot;src/index.tsx&quot;或者 &quot;src/index.ts&quot;或者 &quot;src/index.jsx&quot;或者 &quot;src/index.js&quot;</p>
<p>如果入口文件不存在,则会自动生成入口文件</p>
<h1>修改自定义的 <code>webpack</code> 配置文件</h1>
<p><code>webpack.config.js</code></p>
<pre><code class="hljs language-js"><span class="hljs-keyword">const</span> {
    createconfig,
} = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;@masx200/webpack-react-vue-spa-awesome-config&quot;</span>);

<span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span> = <span class="hljs-function">(<span class="hljs-params">env, argv</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> config = <span class="hljs-title function_">createconfig</span>(env, argv);

    <span class="hljs-comment">//do something with webpackconfig</span>
    <span class="hljs-keyword">return</span> config;
};
</code></pre>
<p><code>package.json</code></p>
<pre><code class="hljs language-json"><span class="hljs-punctuation">{</span>
    <span class="hljs-attr">&quot;scripts&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
        <span class="hljs-attr">&quot;start&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;webpack-react-vue-spa-awesome-config --config=./webpack.config.js --mode=development &quot;</span><span class="hljs-punctuation">,</span>
        <span class="hljs-attr">&quot;build&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;webpack-react-vue-spa-awesome-config --config=./webpack.config.js --mode=production &quot;</span>
    <span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span>
</code></pre>
<h2>启动 webpack-dev-server</h2>
<pre><code>yarn <span class="hljs-keyword">start</span>
</code></pre>
<p>相当于执行</p>
<pre><code>webpack serve  --config ./release/config/webpack.config.js  --mode=development
</code></pre>
<h2>启动 webpack</h2>
<pre><code>yarn build
</code></pre>
<p>相当于执行</p>
<pre><code>webpack  --config ./release/config/webpack.config.js     --mode=production
</code></pre>
<h1>给 浏览器自动添加 <code>polyfill</code></h1>
<pre><code class="hljs language-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;https://cdn.bootcss.com/babel-polyfill/7.12.1/polyfill.min.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h1>内部极简的配置文件</h1>
<h2>内部 只使用 webpack.config.js 和 package.json</h2>
<h3>内部实现原理 仅仅使用一个 webpack.config.js 文件即可同时处理开发模式和生产模式</h3>
<p>webpack 使用配置文件启动的时候,默认不支持通过<code>--mode=development</code>或者<code>--mode=production</code>来设置 webpack 的模式,</p>
<p>在 <code>webpack.config.js</code>文件中通过如下方式来判断 webpack 的模式,即读取<code>process.argv</code>变量来获得传入的参数设置的模式</p>
<pre><code class="hljs language-javascript">process.<span class="hljs-property">argv</span>.<span class="hljs-title function_">includes</span>(<span class="hljs-string">&quot;--mode=production&quot;</span>)
    ? (process.<span class="hljs-property">env</span>.<span class="hljs-property">NODE_ENV</span> = <span class="hljs-string">&quot;production&quot;</span>)
    : (process.<span class="hljs-property">env</span>.<span class="hljs-property">NODE_ENV</span> = <span class="hljs-string">&quot;development&quot;</span>);
</code></pre>
<h1>默认关闭了 <code>eslint</code>！</h1>
<p>可以在<code>vscode</code>中安装<code>eslint</code>插件来检查代码</p>
<h1>集成 postcss,自动增加前缀</h1>
<h1>webpack 中 alias 别名配置,</h1>
<p>可以使用<code>@</code>代替<code>src</code>目录</p>
<h1>局部刷新：</h1>
<p>启用 Webpack 内置的 HMR，增量更新 css 文件和 js 文件，修哪更哪，无需刷新页面即可实时看见修改结果</p>
<h1>动态导入：</h1>
<p>可使用动态导入的语法</p>
<pre><code class="hljs language-javascript"><span class="hljs-title function_">import</span>().<span class="hljs-title function_">then</span>();
</code></pre>
<p>，处理代码时会单独分离此模块，执行页面对应操作时才加载此模块，使用才加载不使用则不加载(代码懒加载)，减少首屏加载代码大小和渲染时间</p>
<h1>代码编译</h1>
<p>使用 style-loader 和 css-loader 处理 CSS，把 CSS 从 JS 中单独抽离出来</p>
<p>使用 sass-loader 处理 Sass，通过 node-sass 编译 sass 文件为 css 文件</p>
<p>使用 less-loader 处理 Less，通过 less 编译 less 文件为 css 文件</p>
<p>使用 babel-loader 根据预设环境和 browserslist 处理编写的 ES6 代码和 TS 代码，并生成浏览器可识别的 ES5 代码</p>
<p>使用 vue-loader 把<code>*.vue</code> 文件编译成 vue 组件转成 js 代码</p>
<h1>代码分割：</h1>
<p>对业务代码进行打包，分割成 WebpackRuntime 代码块、第三方依赖代码块、公共业务代码块、单个业务代码块</p>
<h1>代码合并：</h1>
<p>通过对相同模块、相同功能或复用多次的代码进行整体合并，起到减包作用</p>
<h1>压缩合并：</h1>
<p>CSS 压缩：内置 MiniCssExtractPlugin 和 OptimizeCSSAssetsPlugin，对抽离出来的 CSS 进行压缩去重</p>
<p>JS 压缩：内置 terser，对抽离出来的 JS 进行压缩去重，terser 用于压缩 ES6</p>
<h1>摇树优化：</h1>
<p>启用 Webpack 内置的 Tree Shaking，禁止 babel 把代码转换成 Commonjs 规范</p>
<p>，使用 ESM 规范的静态声明特点来去除不被引用或不被执行的代码块，起到减包作用</p>
<h1>使用 terser-webpack-plugin 删除注释和 console.log</h1>
<h1>生产环境自动关闭 sourcemap，压缩混淆 js 和 css 和 html 代码</h1>
<h1>开发环境支持模块热更新，和 sourcemap</h1>
<h2>使用<code>vue-loader</code>实现<code>Vue</code>组件热更新</h2>
<h2>使用的 loader</h2>
<p>css-loader / babel-loader /worker-loader/vue-loader/url-loader/style-loader/css-loader/sass-loader/file-loader</p>
<h1>worker-loader 可以加载 webworker 的文件，文件后缀名要写成.worker.js</h1>
<p><a href="https://www.webpackjs.com/loaders/worker-loader/">https://www.webpackjs.com/loaders/worker-loader/</a></p>
<h3>修复了使用 webpack.HotModuleReplacementPlugin 和 worker-loader 不兼容的 bug</h3>
<p><a href="https://github.com/webpack/webpack-dev-server/issues/1595">https://github.com/webpack/webpack-dev-server/issues/1595</a></p>
<p><a href="https://github.com/webpack/webpack/issues/6642">https://github.com/webpack/webpack/issues/6642</a></p>
<p><a href="https://github.com/webpack-contrib/worker-loader/issues/174">https://github.com/webpack-contrib/worker-loader/issues/174</a></p>
<p>该错误来自 Web 工作者，因为 Web worker window 上不可用。</p>
<p>webpack.config.js</p>
<pre><code class="hljs language-javascript"><span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span> = {
    <span class="hljs-attr">output</span>: {
        <span class="hljs-attr">globalObject</span>: <span class="hljs-string">`( (typeof window !== &quot;undefined&quot; ? window : false) ||
    (typeof WorkerGlobalScope !== &quot;undefined&quot; ? WorkerGlobalScope : false) ||
    this)`</span>,
    },
};
</code></pre>
<h2>使用的 plugin</h2>
<p>WorkboxWebpackPlugin.GenerateSW/MiniCssExtractPlugin/VueLoaderPlugin/HtmlWebpackPlugin/TerserPlugin/OptimizeCSSAssetsPlugin/webpack.HotModuleReplacementPlugin/WebpackDeepScopeAnalysisPlugin</p>
<h1>提供 workbox 支持单页面应用缓存</h1>
<p><a href="https://developers.google.cn/web/tools/workbox/">https://developers.google.cn/web/tools/workbox/</a></p>
<p>JavaScript Libraries for adding offline support to web apps</p>
<p>Workbox is a set of libraries and Node modules that make it easy to cache assets and take full advantage of features used to build Progressive Web Apps.</p>
<h2>性能</h2>
<p>停止在网络上等待！您可以通过缓存和提供文件来提高 Web 应用程序的性能，这些文件由服务工作人员提供支持。</p>
<h2>弹性</h2>
<p>即使在不可靠的连接上，您的 Web 应用程序仍然可以使用正确的运行时缓存策略。</p>
<h2>增强</h2>
<p>想要构建一个渐进的 Web 应用程序？Workbox 可以轻松创建离线初次体验。</p>
<h1>注册 google 的 workbox 的 serviceworker</h1>
<pre><code class="hljs language-javascript"><span class="hljs-keyword">if</span> (<span class="hljs-string">&quot;production&quot;</span> === process.<span class="hljs-property">env</span>.<span class="hljs-property">NODE_ENV</span>) {
    <span class="hljs-keyword">if</span> (
        location.<span class="hljs-property">hostname</span> !== <span class="hljs-string">&quot;localhost&quot;</span> &amp;&amp;
        <span class="hljs-string">&quot;127.0.0.1&quot;</span> !== location.<span class="hljs-property">hostname</span>
    ) {
        <span class="hljs-string">&quot;serviceWorker&quot;</span> <span class="hljs-keyword">in</span> navigator &amp;&amp;
            <span class="hljs-variable language_">window</span>.<span class="hljs-title function_">addEventListener</span>(
                <span class="hljs-string">&quot;load&quot;</span>,
                <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) {
                    navigator.<span class="hljs-property">serviceWorker</span>
                        .<span class="hljs-title function_">register</span>(<span class="hljs-string">&quot;service-worker.js&quot;</span>)
                        .<span class="hljs-title function_">catch</span>(<span class="hljs-function">() =&gt;</span> {});
                },
                { <span class="hljs-attr">once</span>: <span class="hljs-literal">true</span> }
            );
    }
}
</code></pre>
<p>或者</p>
<pre><code class="hljs language-javascript"><span class="hljs-keyword">import</span> <span class="hljs-string">&quot;@masx200/webpack-react-vue-spa-awesome-config/registerserviceworker.js&quot;</span>;
</code></pre>
<h2>站在巨人的肩膀上</h2>
<h3>借鉴了 Facebook 开发的 <a href="https://github.com/facebook/create-react-app">Create-react-app</a>的 webpack 配置的一部分，并进行了大量魔改</h3>
<p><a href="https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/config/webpack.config.js">https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/config/webpack.config.js</a></p>
<p><a href="https://github.com/facebook/create-react-app">https://github.com/facebook/create-react-app</a></p>
<p><a href="https://npm.taobao.org/package/react-scripts">https://npm.taobao.org/package/react-scripts</a></p>
<h1>支持 webpack5</h1>
<p>1.&quot;webpack-dev-server&quot;无法启动</p>
<p><a href="https://github.com/webpack/webpack/issues/13367">https://github.com/webpack/webpack/issues/13367</a></p>
<p>将命令<code>webpack-dev-server</code>替换成<code>webpack serve</code></p>
<ol start="2">
<li></li>
</ol>
<p><a href="https://github.com/webpack-contrib/copy-webpack-plugin">https://github.com/webpack-contrib/copy-webpack-plugin</a></p>
<p>由于插件<code>webpack-copyfiles-plugin</code>已经不兼容了，直接替换成
<code>copy-webpack-plugin</code></p>
<ol start="3">
<li></li>
</ol>
<p><a href="https://github.com/webpack/webpack/issues/11637">https://github.com/webpack/webpack/issues/11637</a></p>
<p>将<code>NamedModulesPlugin</code> 替换为 <code>optimization.moduleIds: &#39;named&#39;</code></p>
<ol start="4">
<li></li>
</ol>
<p><a href="https://webpack.js.org/plugins/split-chunks-plugin/#splitchunksname">https://webpack.js.org/plugins/split-chunks-plugin/#splitchunksname</a></p>
<p>修改了 configuration.optimization.splitChunks.name</p>
<p>configuration.optimization.splitChunks.name should be one of these:
false | string | function
-&gt; Give chunks created a name (chunks with equal name are merged).</p>
<ol start="5">
<li></li>
</ol>
<p><a href="https://webpack.docschina.org/blog/2020-10-10-webpack-5-release/#changes-to-the-structure">https://webpack.docschina.org/blog/2020-10-10-webpack-5-release/#changes-to-the-structure</a></p>
<p><code>[hash]</code> 作为完整的编译 hash 值，现已被弃用
迁移：使用 <code>[fullhash]</code> 代替，或最好选用其他 hash 选项</p>
<ol start="6">
<li></li>
</ol>
<p><a href="https://github.com/GoogleChrome/workbox/issues/1790">https://github.com/GoogleChrome/workbox/issues/1790</a></p>
<p>WARNING in GenerateSW has been called multiple times, perhaps due to running webpack in --watch mode. The precache manifest generated after the first call may be inaccurate! Please see for more information.</p>
<p>只在生产环境运行插件 ，开发环境不运行此插件。</p>
<p>new WorkboxWebpackPlugin.GenerateSW</p>
<ol start="7">
<li></li>
</ol>
<p><a href="https://webpack.docschina.org/configuration/module/#ruletype">https://webpack.docschina.org/configuration/module/#ruletype</a></p>
<p>ERROR in ./src/index.js 1:0<br>Module parse failed: &#39;import&#39; and &#39;export&#39; may appear only with &#39;sourceType: module&#39; (1:0)</p>
<pre><code class="hljs language-js">[
    {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.(js|mjs|jsx|ts|tsx)$/</span>,
        <span class="hljs-attr">type</span>: <span class="hljs-string">&quot;javascript/auto&quot;</span>,
        <span class="hljs-attr">loader</span>: <span class="hljs-built_in">require</span>.<span class="hljs-title function_">resolve</span>(<span class="hljs-string">&quot;babel-loader&quot;</span>),
    },
];
</code></pre>
<p>8.soucemap</p>
<p><a href="https://webpack.docschina.org/configuration/devtool/#root">https://webpack.docschina.org/configuration/devtool/#root</a></p>
<pre><code class="hljs language-js"><span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span> = { <span class="hljs-attr">devtool</span>: isEnvDevelopment ? <span class="hljs-string">&quot;inline-source-map&quot;</span> : <span class="hljs-literal">false</span> };
</code></pre>
<p>9.Hot Module Replacement 失效解决办法</p>
<p><a href="https://www.cnblogs.com/guangzan/p/14744226.html">https://www.cnblogs.com/guangzan/p/14744226.html</a></p>
<p><a href="https://webpack.docschina.org/guides/hot-module-replacement/">https://webpack.docschina.org/guides/hot-module-replacement/</a></p>
<p>原因分析</p>
<p>项目根目录存在 .browserslistrc 文件，或者 package.json 存在 “browserslist”。</p>
<pre><code class="hljs language-js"><span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span> = {
    <span class="hljs-attr">target</span>: <span class="hljs-string">&quot;web&quot;</span>,
    <span class="hljs-attr">devServer</span>: {
        <span class="hljs-attr">hot</span>: <span class="hljs-literal">true</span>,
    },
    <span class="hljs-attr">plugins</span>: [<span class="hljs-keyword">new</span> webpack.<span class="hljs-title class_">HotModuleReplacementPlugin</span>()],
};
</code></pre>
